﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace HB.MsgBus
{
#if gggg
    /// <summary>
    /// 使用委托实例的拓展方法
    /// </summary>
    public static class DelegateExpand
    {
#region 订阅
        /// <summary>
        /// 强制在UI线程执行订阅，需先RegsterUIThread
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">指定此次订阅者的id</param>
        /// <param name="dele"></param>
        /// <param name="group">指定此次订阅者的分组</param>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeOnUIThread<T>(this T dele, T action, string id = null, string group = null, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeOnUIThread<T>(action, id, group, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 订阅
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">指定此次订阅者的id</param>
        /// <param name="group">指定此次订阅者的分组</param>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeByIdGroup<T>(this T dele, string id, string group, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeByIdGroup(id, group, action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 只通过id订阅,同一个id的事件只能存在一个
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">指定此次订阅者的id</param>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeById<T>(this T dele, string id, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeById<T>(id, action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 通过id订阅，只能执行一次的订阅
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">指定此次订阅者的id</param>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeByIdOnce<T>(this T dele, string id, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeByIdOnce<T>(id, action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 只能执行一次的订阅
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeOnce<T>(this T dele, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeOnce<T>(action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 订阅
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">指定此次订阅者的id</param>
        /// <param name="group">指定此次订阅者的分组</param>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void SubscribeByIdGroupOnce<T>(this T dele, string id, string group, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.SubscribeByIdGroupOnce(id, group, action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
        /// <summary>
        /// 订阅事件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action">注入T类型的委托</param>
        /// <param name="subscriber">订阅者对象(任意对象)，内部使用弱引用，当对象被回收时，该订阅自动失效，不传则不检查</param>
        /// <param name="SubscribeFilePath">订阅者文件路径，自动生成，无需手动填写</param>
        /// <param name="SubscribeLineNumber">订阅者代码行数，自动生成，无需手动填写</param>
        /// <param name="SubscriptFunctionName">订阅者函数名，自动生成，无需手动填写</param>
        public static void Subscribe<T>(this T dele, T action, object subscriber = null, [CallerFilePath] string SubscribeFilePath = null, [CallerLineNumber] int SubscribeLineNumber = 0, [CallerMemberName] string SubscriptFunctionName = null) where T : Delegate
        {
            MsgBus.Subscribe<T>(action, subscriber, SubscribeFilePath, SubscribeLineNumber, SubscriptFunctionName);
        }
#endregion
#region 同步发布
        /// <summary>
        /// 同步发布（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="condition"></param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="callBack">结果回调</param>
        public static void PublishIf<T>(this T dele, bool condition, Action<T> invoteParam, Action<int> callBack = null) where T : Delegate
        {
            MsgBus.PublishIf<T>(condition, invoteParam, callBack);
        }
        /// <summary>
        /// 同步发布（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="callBack">结果回调</param>
        public static void Publish<T>(this T dele, Action<T> invoteParam, Action<int> callBack = null) where T : Delegate
        {
            MsgBus.Publish(invoteParam, callBack);
        }
        /// <summary>
        /// 同步发布（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="condition"></param>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="callBack">结果回调</param>
        public static void PublishByGroupIdIf<T>(this T dele, bool condition, string group, string id, Action<T> invoteParam, Action<int> callBack = null) where T : Delegate
        {
            MsgBus.PublishByGroupIdIf(condition, group, id, invoteParam, callBack);
        }
        /// <summary>
        /// 同步发布（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="callBack">结果回调</param>
        public static void PublishByGroupId<T>(this T dele, string group, string id, Action<T> invoteParam, Action<int> callBack = null) where T : Delegate
        {
            MsgBus.PublishByGroupId(group, id, invoteParam, callBack);
        }
        /// <summary>
        /// 同步发布并返回（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <returns></returns>
        public static List<T2> PublishForResult<T, T2>(this T dele, Func<T,T2> invoteParam) where T : Delegate
        {
            return MsgBus.PublishForResult<T, T2>(invoteParam);
        }
        /// <summary>
        /// 同步发布并返回（当前线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <returns></returns>
        public static List<T2> PublishForResultByGroupId<T, T2>(this T dele, string group, string id, Func<T, T2> invoteParam) where T : Delegate
        {
            return MsgBus.PublishForResultByGroupId(group, id, invoteParam);
        }
#endregion

#region 异步发布
        /// <summary>
        /// 异步发布返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="asyncCallBack">结果回调</param>
        public static Task PublishAsyncForResultByGroupId<T, T2>(this T dele, string group, string id, Func<T, T2> invoteParam, Action<List<T2>> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsyncForResultByGroupId(group, id, invoteParam, asyncCallBack);
        }
        /// <summary>
        /// 异步发布发布返回
        /// </summary>
        /// <typeparam name="T">委托类型</typeparam>
        /// <typeparam name="T2">返回值类型</typeparam>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <returns></returns>
        public static Task<List<T2>> PublishAsyncForResultByGroupId<T, T2>(string group, string id, Func<T, T2> invoteParam) where T : Delegate
        {
            return MsgBus.PublishAsyncForResultByGroupId(group, id, invoteParam);
        }
        /// <summary>
        /// 异步发布返回
        /// </summary>
        /// <typeparam name="T">委托类型</typeparam>
        /// <typeparam name="T2">返回值类型</typeparam>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <param name="asyncCallBack">结果回调</param>
        public static Task PublishAsyncForResult<T, T2>(this T dele, Func<T, T2> invoteParam, Action<List<T2>> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsyncForResult(invoteParam, asyncCallBack);
        }
        /// <summary>
        /// 异步发布返回
        /// </summary>
        /// <typeparam name="T">委托类型</typeparam>
        /// <typeparam name="T2">返回值类型</typeparam>
        /// <param name="invoteParam">委托调用，如 t=>t(1,2)</param>
        /// <returns></returns>
        public static Task<List<T2>> PublishAsyncForResult<T, T2>(Func<T, T2> invoteParam) where T : Delegate
        {
            return MsgBus.PublishAsyncForResult(invoteParam);
        }
        /// <summary>
        /// 异步发布（后台线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam"></param>
        /// <param name="asyncCallBack"></param>
        public static Task PublishAsyncByGroupId<T>(this T dele, string group, string id, Action<T> invoteParam, Action<int> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsyncByGroupId(group, id, invoteParam, asyncCallBack);
        }
        /// <summary>
        /// 异步发布（后台线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="condition"></param>
        /// <param name="group">null为不指定</param>
        /// <param name="id">null为不指定</param>
        /// <param name="invoteParam"></param>
        /// <param name="asyncCallBack"></param>
        public static Task PublishAsyncByGroupIdIf<T>(this T dele, bool condition, string group, string id, Action<T> invoteParam, Action<int> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsyncByGroupIdIf(condition, group, id, invoteParam, asyncCallBack);
        }
        /// <summary>
        /// 异步发布（后台线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="invoteParam"></param>
        /// <param name="asyncCallBack"></param>
        public static Task PublishAsync<T>(this T dele, Action<T> invoteParam, Action<int> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsync(invoteParam, asyncCallBack);
        }
        /// <summary>
        /// 异步发布（后台线程执行）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="condition"></param>
        /// <param name="invoteParam"></param>
        /// <param name="asyncCallBack"></param>
        public static Task PublishAsyncIf<T>(this T dele, bool condition, Action<T> invoteParam, Action<int> asyncCallBack = null) where T : Delegate
        {
            return MsgBus.PublishAsyncIf(condition, invoteParam, asyncCallBack);
        }
#endregion
        /// <summary>
        /// 清理指定T  topic的订阅，将在运行时判定清理。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        public static void ClearSubscription<T>(this T dele, string id) where T : Delegate
        {
            MsgBus.ClearSubscription<T>(id);
        }
        /// <summary>
        /// 获取指定topic的订阅者群
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<EventRouterItemBase> GetSubscriptActicedPoints<T>(this T dele)
        {
            return MsgBus.GetSubscriptActicedPoints<T>();
        }
    }
#endif
}
